/** @jsxImportSource @emotion/react */
import * as React from "react";
import {css} from "@emotion/react";
import {
    Button,
    CommitInput,
    DdMenu, DdMenuItem,
    Dialog, DialogClose, DialogContent, DialogDescription, DialogHeading,DialogTrigger,
    IconAnchor, IconArchive,
    IconButton, IconEyeOff, IconMenu,
    IconMoreVertical, IconPlus,
    IconRefButton, IconRefreshCcw, IconTrash2,
    IconX,
    Input,
    InputLine,
    InputPure, Itext,
    ListFlexRow, MenuItem, Pager,
    Popover, PopoverClose, PopoverContent, PopoverDescription, PopoverHeading, PopoverRefer,
    Select, Tab, TabPanel, Tabs, Text,
    Touchable,
    useTheme
} from "customize-easy-ui-component";
// import {Dialog,DialogClose, DialogContent, DialogDescription, DialogHeading,DialogTrigger} from "@/comp/Dialog";
// import {Popover, PopoverClose, PopoverContent, PopoverDescription, PopoverRefer, PopoverHeading} from "@/comp/Popover";
import {DeviceClassSelect} from "../../device/DeviceClassSelect";
import {SuffixRefInput} from "customize-easy-ui-component/esm/Form";
import {eqpTypeAllMap} from "../../dict/eqpComm";
import {reportStatusMap} from "../../task/DeviceListItem";
import {FeesListItem$key} from "../../task/fee/__generated__/FeesListItem.graphql";
import {useContext} from "react";
import RoutingContext from "../../routing/RoutingContext";
import {useMeasure} from "customize-easy-ui-component/esm/Hooks/use-measure";
import {eqpUseStateMap} from "../../pipeline/edit/管道单元";
import {useMediaLayout} from "use-media";
import {useWindowSize} from "customize-easy-ui-component/esm/Hooks/use-window-size";
import {DetailTaskID, IdName, IPipingUnitEntity, PipingUnit_KeyEnum} from "../../comp/ChoosePipingUnits";
import {eqpRegStateMap} from "../../device/edit/CommnBase";

interface MultiSelectProps {
    dxDevs: Array<IPipingUnitEntity>;      // any [];
    //编辑模式： 删除某一个设备回调。  React.Dispatch<React.SetStateAction<any []>>;  Array<IPipingUnitEntity>
    setDxDevs:  (value: Array<IPipingUnitEntity>) => void;
    //删除这个收费项目
    // onCancel?: () => void;
    //切换数据并显示 管道单元的明细列表。
    // onViewPipeList?: ([]) => void;
    //弹出框跟踪某焦点: 编辑框Input?。
    refer?: any;    //React.ReactNode;
    //因为要应对两种使用场合，一个是编辑框点击弹出的，一个是设备浏览窗口的按钮触发本hook的，前一个场合需要添加一些附加按钮功能。
    //加入按钮: 更多设备跳转路由需要保存编辑器现状。【特招】组件以及回调函数全部都来自注入不在本hook代码之中的。
    addBtn?: React.ReactNode;
    intOpen?: boolean;
    //默认可编辑形态：可删除已选择设备。
    edit?: boolean;
    //清除当前的编辑选择，或者说reset恢复编辑之前的数据。恢复成来自数据库的设备集合，json场景也是直接来在数据库的。
    onReset?: () => void;
    //选定这个单元: 所要执行的回调。
    onSelect?: (sel: IPipingUnitEntity, index:number) => void;
}
/**抽离 数据，还抽离部分按钮， 注入回调钩子。
 * 【好例子：代码复用能力】Hook,免于类似功能网页的复制修改做法了，可以一次性修改多个代码的引用拷贝。
 * dxDevs 规范的输入设备列表, setDxDevs 删除某个设备；
 * 对比的：【伪对话框】模式也是代码复用的一种，是特殊页面：比如搜索设备台账，搜索单位台账这种的，大范围挑选，有很多的过滤器字段，编辑器需要挑选某一个设备或单位。
 * 报错：Rendered more hooks than during the previous render.不能直接上？  {dxDevs?.map( (eqp, i) => { const [detailView, setDetailView] = React.useState(false);return (要封装组件。
 * Popover【苦逼】对话框高度方向不会超出屏幕时刻最好加Refer={}否则弹出框不能正好进视野，但是对话框高度方向不会超出屏幕高度情况就相反应该不要添加Refer={}，加了无法显示全部区域。
 * 更大问题，设备数量不确定，对话框内容区域高度无法预计：div高度多大？Size.Hook(Content.Div))然后css?:&&。 #放弃使用Popover组件改用Dialog。
 *设备详细信息，本质是显示sessionStorage里，向上级追溯：可能graphQL内省获得，但也有可能来自非结构化的json解析内容（这情况不是最新数据，也不是全字段）对某设备选定进入集合时快照，每个设备都不同时间点快照。
 * 在快照模式（后端非结构换存储devs[]多选集合被存储进入json的，并非通常的JPA实体关联关系存储的）这情况下，历史上挑选的快照会延续下去，除非删除后重新选择该设备的才会更新快照附加对象字段。
 * 目前不考虑在'/pipeline/:pId/:ppuId'页面嵌入本多选组件。都到ES列表'/pipingUnit/:pId/:ppuId'去做。
 *  */
export function usePipingUnitMultiSelect({ dxDevs, setDxDevs, refer,
                           addBtn, intOpen=false, edit=true,onReset,onSelect
}: MultiSelectProps) {
    //这里eqp对象数据仰仗父辈传递来的
    const theme = useTheme();
    //const filt= JSON.parse(sessionStorage['任务过滤']??'{}');
    const [open, setOpen] = React.useState(intOpen);
    const { history } = useContext(RoutingContext);
    //【注意】特殊性： 编辑器对话框的组件可能直接集成到触发按钮甚至菜单项DdMenuItem?里面了。
    //模式区分：【明确表示进入编辑模式的】 只读形态 ，转为可编辑的。
    //设备列表的显示内容：切换为某个字段。
    const [viewzd, setViewzd] = React.useState('code');
    //只好提到上一級組件：共享已經選定的狀態
    const [tab, setTab] = React.useState(0);
    //电脑屏幕    // const wideScr = useMediaLayout(`(min-width: 920px)`);
    //横屏手机    // const shortScr = useMediaLayout(`(max-height: 480px)`);
    const {innerHeight, innerWidth}= useWindowSize();


  const view=(
     <>
         <Dialog open={open} onOpenChange={setOpen} modal={false}>
             {
                 refer && (
                     <DialogTrigger className="DialogTrigger" asChild >
                         {refer}
                     </DialogTrigger>
                 )
             }
             <DialogContent >
                 <DialogHeading asChild>
                     <DdMenu label="多个管道单元选择" tight={true}>
                         <DdMenuItem label="单元编号"
                                     onClick={async(e) => {
                                         setViewzd('code');
                                     }}/>
                         <DdMenuItem label="监察注册登记码"
                                     onClick={async(e) => {
                                         setViewzd('rno');
                                     }}/>
                         <DdMenuItem label="管道名称"
                                     onClick={async(e) => {
                                         setViewzd('name');
                                     }}/>
                     </DdMenu>
                 </DialogHeading>
                 <DialogDescription
                     style={{
                         display: "flex",
                         flexWrap: 'wrap',
                     }}
                 >
                     {dxDevs?.map( (eqp, i) => {
                        //底下的<PopoverContent 无法用style={}来修饰，只好改为css={{“  !important', 来覆盖掉底层配置；
                       return (<Popover key={i}>
                                 <PopoverRefer  style={{
                                     fontSize: 'large',
                                     minWidth: '3rem',
                                     margin: '3px 5px',
                                 }}>
                                     {eqp[viewzd as PipingUnit_KeyEnum] || '空的'}
                                 </PopoverRefer>
                                 <PopoverContent css={{
                                         border: 'none !important',
                                         padding: '0 !important',
                                     }}
                                 >
                                     <PopoverDescription
                                         style={{
                                             display: "flex",
                                             flexWrap: 'wrap',
                                         }}
                                         css={{
                                             // width: `calc(100vw - ${theme.iconSizes.md} - 2 * ${theme.spaces.sm})`,
                                             width: '100vw',
                                             maxWidth: innerWidth!>820? '820px' : undefined,
                                         }}
                                     >
                                         <OutlineDevice eqp={eqp} tab={tab} setTab={setTab} viewHeight={innerHeight!}/>
                                     </PopoverDescription>

                                     <div style={{
                                         display: "flex",
                                         width: '100%',
                                         justifyContent: 'space-around',
                                         minWidth: '16rem',
                                     }}>
                                         <PopoverClose style={{
                                             margin: 'unset',      //底层ForwardRef组件用{...props}接收并替换掉style={}可以成功覆盖
                                         }}>
                                             <IconX/>
                                         </PopoverClose>
                                         <Button  variant="outline"   label="台账"
                                                  onClick={async (e) => {
                                                      history.push(`/pipingUnit/${eqp?.pipe?.id}/`+eqp?.id);
                                                  } }
                                         >台账</Button>
                                         { onSelect &&
                                             <IconButton  variant="ghost"  icon={<IconAnchor />}  label="选定这个单元"
                                                          onClick={async (e) => {
                                                              onSelect(eqp, i);
                                                              setOpen(false);
                                                          } }
                                             />
                                         }
                                         { edit &&
                                             <IconButton
                                                 variant="ghost"
                                                 icon={<IconTrash2 />}
                                                 label="删除"
                                                 onClick={async (e) => {
                                                     //这里不能使用.splice()来做；   需要不可变变量。
                                                     const newarr=dxDevs?.slice(0,i).concat(dxDevs?.slice(i+1));
                                                     setDxDevs(newarr);
                                                     e.preventDefault();
                                                     e.stopPropagation();
                                                 } }
                                             />
                                         }
                                     </div>
                                 </PopoverContent>
                             </Popover>);

                     })}
                 </DialogDescription>

                 <div style={{
                     display: "flex",
                     width: '100%',
                     justifyContent: 'space-around',
                     minWidth: '16rem',
                 }}>
                     <DialogClose>
                         <IconX/>
                     </DialogClose>
                     { edit && <Button  variant="outline"   label="复位或清空"
                                     onClick={async (e) => {
                                         if(onReset)   await onReset!();
                                         else  setDxDevs([]);
                                         e.preventDefault();
                                         e.stopPropagation();
                                     } }
                          >{onReset? '复位' : '清空'}</Button>
                     }
                     {addBtn}
                 </div>
             </DialogContent>
         </Dialog>
     </>
  );

  //页面复用的Hook
  return {
     view,
     open,
     setOpen
  };
}


interface OutlinePipingUnitProps extends React.HTMLAttributes<HTMLDivElement> {
    //例外 重塑类型: 不仅仅来自Relay 还有可能从sessionStorage读取。
    eqp: IPipingUnitEntity;
    tab: number,
    setTab: React.Dispatch<React.SetStateAction<number>>,
    //已明确可视区域高度。
    viewHeight: number,
}
/**有可能是从非内省的json{}关联直接恢复一部分的设备数据的，不一定都是graphQL内省字段得到的。
 * 分组地显示基本的设备台账参数字段。
 * 为了让useMeasure(dynctRef)生效，只好拆分出来：新的独立子组件；
 * useMeasure测量有局限？
 * ListFlexRow以及TabPanel俩都没法注入Ref;所以只好插入一个<div ref={ref}}>控制层方式了。
 * [目的] Pager包含几个分页面的，但是分组内容显示的区域也是动态的大小，首先限定宽度X方向最大值，就能获取每一个分页面的高度Y方向最终像素px; 取最大高度值。
 * 【最后】改成Popover内容高度上设置可滚动属性为佳。根据屏幕高度大小设置合理的最大Popover视口高度，首先也要依据屏幕宽度合理敲定最大的视口宽度。
 * 手机横屏最大宽度920，横屏最小高度360最大高度480；
 * */
const OutlineDevice: React.FunctionComponent<OutlinePipingUnitProps> = (
    {
        eqp,tab,setTab, viewHeight,
        ...other
    }) => {
    const theme = useTheme();
    //[].map{Popover }为何无法保留历史选择TAB;
    // const [tab, setTab] = React.useState(0);
    //内容是动态没有固定宽度的。需要高度方向或水平方向有一个规定大小才行。 @底下ref跟踪是<TabPanel  <div >  <ListFlexRow>的中间div; 估计最大2个对比即可。
    const dynctRef0 = React.useRef<HTMLDivElement>(null);
    const dynctRef2 = React.useRef<HTMLDivElement>(null);
    const rectRef0=useMeasure(dynctRef0 as React.RefObject<HTMLElement>);
    const rectRef2=useMeasure(dynctRef2 as React.RefObject<HTMLElement>);
    const dynHeight = Math.max(
        dynctRef0.current ? (rectRef0?.height as number) : 0,
        dynctRef2.current ? (rectRef2?.height as number) : 0
    );
    //横屏手机：Popover中心线弹出的不包含底下<ListFlexRow>内容之外的区域高度方向上正常固定会扣除76px｛关闭按钮+TABS按钮条+Refer参考组件高度的一半大小｝？这些控件水平方向预期不动的情形；
    const finalHeight= Math.min( (viewHeight/2 -74) , dynHeight);

    return (
        <React.Fragment>
            <Tabs value={tab} onChange={i => setTab(i)}
                  css={{
                      width: '100%',
                      //子元素选择器  >不能跨代选取  h1.warning + p { ...} 会选择所有有用warning类的h1元素后面紧跟的p兄弟元素。 "& .Tabs__container":
                      //下一级标签的修改样式办法： & 表示在嵌套层次中回溯一层 /空格' '后代选择器/.class名字选择器 <div class="nn11 Tabs__container">点号后面就是类。
                      "&>.Tabs__container":{
                          display: 'inline-flex',
                          justifyContent: 'center',
                      }
                  }}
            >
                <Tab id="0">基础编码</Tab>
                <Tab id="1">监管其它</Tab>
            </Tabs>
            <Pager   lazyLoad={false}  noBind={false}
                     value={tab}   onRequestChange={i => setTab(i)}
                     style={{
                         height: `${finalHeight}px`,     //横屏手机实际测试最佳的取值高度360px最佳116，;。
                     }}
                     paneStyle={{
                         // marginBottom: `20px`,
                     }}
            >
                <TabPanel id="0"
                          css={{
                              height: '100%',
                              overflowY: 'auto',
                          }}
                >
                    <div ref={dynctRef0}>
                        <ListFlexRow >
                            <Text>{ eqp?.code || '~' }</Text>
                            <Itext>{ eqp?.rno || '/'}</Itext>
                            <Text>{ eqp?.name || '#'}</Text>
                        </ListFlexRow>
                        <ListFlexRow >
                            <Text>{ eqp?.start || '-'}</Text>
                            <Text>{ eqp?.stop || ';'}</Text>
                        </ListFlexRow>
                        <ListFlexRow >
                            <Text>{ eqp?.pipe?.useu?.name || '*' }</Text>
                            <Text>{ eqp?.proj || '/'}</Text>
                        </ListFlexRow>
                    </div>
                </TabPanel>
                <TabPanel id="1"
                          css={{
                              height: '100%',
                              overflowY: 'auto',
                          }}
                >
                    <div ref={dynctRef2}>
                        <ListFlexRow>
                            <Text>{eqpRegStateMap.get(eqp?.reg!) || ','}</Text>
                            <Text>{eqpUseStateMap.get(eqp?.ust!) || '?'}</Text>
                        </ListFlexRow>
                        <ListFlexRow>
                            <Text>{ eqp?.nxtd1 || '--'}</Text>
                            <Itext>{ eqp?.nxtd2 || '^' }</Itext>
                            <Text>{ eqp?.leng || '?'}米</Text>
                        </ListFlexRow>
                        <ListFlexRow>
                            <Text>{ eqp?.pipe?.cod || '$' }</Text>
                            <Text>{ eqp?.pipe?.oid || '#' }</Text>
                        </ListFlexRow>
                    </div>
                </TabPanel>
            </Pager>
        </React.Fragment>
    );
};

